import React, { useEffect, useState } from 'react';
import { connect, Dispatch } from 'umi';

import { Card, Input, List, Empty, Spin } from 'antd';
import Widget from '@/components/Widget';

import { WidgetsItem, IChartConfig, IChartDataFilterConfigs, IndexDetailItem } from '../type';
import { ConnectState } from '@/models/connect';
import { IResponse } from '@/models/connect';

import { VISUALTYPES } from '@/pages/SelfQuery/constants';
import { debounce } from 'lodash';

interface IndexProps {
  dispatch: Dispatch;
  widgets: Array<WidgetsItem>;
  widgetRecords: Array<number>;
  projectId: number;
  indexDetail: IndexDetailItem;
  loading?: boolean;
}

import styles from './style.less';

const IndexLibrary: React.FC<IndexProps> = (props) => {
  const { dispatch, widgets, widgetRecords, projectId, indexDetail, loading } = props;
  const [searchValue, setSearchValue] = useState<string>(''); // 搜索关键词
  const [searchList, setSearchListS] = useState<Array<WidgetsItem>>([]); // 搜索出来的列表
  const [selectRecords, setSelectRecords] = useState<any>({}); // 选中展示的指标

  // 搜索
  const serach = debounce((value: string) => {
    let viewWidgets: any = [];
    setSelectRecords('');
    if (value !== '') {
      const vals = value.split(/\s+/);
      if (vals.length == 3) {
        // 假如字段存在多个空格，判断为进行树形搜索
        threeSearch(vals);
        return;
      }
      widgets.forEach((widget: any) => {
        if (widget.text.indexOf(value) != -1) {
          viewWidgets.push(widget);
        }
      });
      setSearchListS(viewWidgets);
    }
  }, 200);

  // 树形结构搜索
  const threeSearch = (vals: Array<string>) => {
    if (vals.length != 3) {
      return;
    }

    let viewWidgets: Array<any> = [];
    const index = vals[2];
    widgets.forEach((widget: any) => {
      const { text, config } = widget;
      if (text.indexOf(index) != -1 && index.trim() != '') {
        const { customFilters } = config;
        let dateFilters = [];
        let levelFilters = [];
        if (customFilters && customFilters.length) {
          dateFilters = customFilters.filter((v: any) => v.visualType == VISUALTYPES.Date);
          levelFilters = customFilters.filter((v: any) => v.visualType == VISUALTYPES.CostCenter);
        }
        if (dateFilters && dateFilters.length && levelFilters && levelFilters.length) {
          viewWidgets.push(widget);
        }
      }
    });
  };

  // 监听搜索框的值改变
  const onSearchChange = (e: any) => {
    setSearchValue(e.target.value);

    if (!e.target.value) {
      setSearchValue('');
    } else {
      serach(e.target.value);
    }
  };

  // 选择的指标
  const select = (item: WidgetsItem) => {
    item.widgetId = item.id;
    item.widgetName = item.text;
    setSelectRecords(item);
    // 记录感兴趣指标
    setWidgetRecord(item);

    // 清除下钻路径和筛选条件
    dispatch({
      type: 'widget/clearCondition',
    });

    // 获得 获取指标图表数据所需参数
    dispatch({
      type: 'panel/fetchWidgetParams',
      payload: { id: item.widgetId },
      callback: (response: IResponse) => {
        const { header, payload } = response;
        if (header.code === 200) {
          // 请求参数转换
          const config: IChartConfig = JSON.parse(payload.config);
          const metrics = config.metrics;
          const viewId = payload.viewId;
          let body: IChartDataFilterConfigs = {
            groups: config.cols.map((v: any) => v.name),
            aggregators: [],
            filters: config.filters.map((filter: any) => filter.config.sqlModel[0]),
            orders: config.orders,
            pageNo: 0,
            pageSize: 0,
            nativeQuery: false,
            cache: config.cache,
            expired: config.expired,
            flush: false,
          };
          let aggregators: Array<any> = [];
          metrics.forEach((metric) => {
            let aggregator = {
              column: metric.name.split('@')[0],
              func: metric.agg,
              calculate: metric.calculate,
            };
            aggregators.push(aggregator);
          });
          body.aggregators = aggregators;

          // 富文本类型，不请求数据
          if (config.selectedChart === 15) {
            return;
          }

          // 请求图表数据
          dispatch({
            type: 'panel/fetchWidgetData',
            payload: { id: viewId, body: JSON.stringify(body) },
            callback: (res: IResponse) => {
              const { header, payload: dataRecord } = res;
              if (header && header.code === 200) {
                const obj = {
                  dataRecord: {},
                  configs: null,
                  filterConfigs: {},
                  widget: item,
                  subscribe: null,
                };
                if (!dataRecord) {
                  obj.dataRecord = { resultList: [], columns: [] };
                  return;
                }
                obj.dataRecord = dataRecord;
                obj.filterConfigs = body;
                obj.subscribe = payload.isSubscribe;

                if (Object.keys(dataRecord).length > 0) {
                  obj.configs = JSON.parse(response.payload.config);
                }
                dispatch({
                  type: 'widget/fetchIndexDetail',
                  payload: obj,
                });
              }
            },
          });
        }
      },
    });
  };

  // 记录感兴趣
  const setWidgetRecord = (widget: any) => {
    let datas = Object.assign([], widgetRecords);
    if (datas.filter((id: any) => id == widget.id).length > 0) {
      datas = datas.filter((id: any) => id != widget.id);
      datas.unshift(widget.id);
    } else {
      datas = datas.filter((id: any) => id != widget.id);
      if (datas.length >= 3) {
        datas.pop();
      }
      datas.unshift(widget.id);
    }
    dispatch({
      type: 'indexLibrary/fetchUpdateWidgetRecords',
      payload: datas,
    });
  };

  useEffect(() => {
    // 获取所有的指标列表
    dispatch({
      type: 'indexLibrary/fetchDashboards',
    });

    // 获取感兴趣列表 ID
    dispatch({
      type: 'indexLibrary/fetchInitWidgetRecords',
    });

     // 清除查看的指标详情数据 解决各页面查看指标详情相互影响
     dispatch({
      type: 'widget/fetchIndexDetail',
      payload: {},
    });
  }, []);

  // 遍历获得感兴趣的指标
  const records = widgetRecords
    .map(
      (w: any) =>
        widgets.filter((v: any) => v.id == w && (v.projectId == projectId || projectId == 0))[0],
    )
    .filter((v: any) => v);

  return (
    <div className={styles.indexLibrary}>
      <Card
        style={{ width: 260 }}
        bordered={false}
        title={<Input placeholder="搜索指标" onChange={onSearchChange} allowClear />}
      >
        <List
          header={searchValue ? '' : <div>可能感兴趣：</div>}
          dataSource={searchValue ? searchList : records}
          split={false}
          size={searchValue ? 'default' : 'small'}
          locale={{
            emptyText: (
              <Empty
                description={searchValue ? '无搜索结果~' : '快去搜索你感兴趣的指标吧~'}
                image={Empty.PRESENTED_IMAGE_SIMPLE}
              />
            ),
          }}
          renderItem={(item) => (
            <List.Item>
              <span
                className={
                  JSON.stringify(selectRecords) === JSON.stringify(item)
                    ? `${styles.interest} ${styles.active}`
                    : styles.interest
                }
                onClick={() => {
                  select(item);
                }}
              >
                {item.text}
              </span>
            </List.Item>
          )}
        />
      </Card>
      <div className={styles.detailWrap}>
        <div className={styles.detail}>
          {loading && (
            <div className={styles.loading}>
              <Spin size="large" />
            </div>
          )}

          {indexDetail.dataRecord && indexDetail.configs ? (
            // 指标详情
            <Widget parentTitle="指标库" />
          ) : (
            <div className={styles.none}>
              <Empty description="请选择指标" />
            </div>
          )}
        </div>
      </div>
    </div>
  );
};
export default connect(({ widget, indexLibrary, loading }: ConnectState) => ({
  widgets: indexLibrary.widgets,
  widgetRecords: indexLibrary.widgetRecords,
  projectId: indexLibrary.projectId,
  indexDetail: widget.indexDetail,
  loading: loading.effects['panel/fetchWidgetData'],
}))(IndexLibrary);
